package com.jymj.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 文件压缩
 *
 * @author Lzh
 * @date 2021/3/3 16:09
 */
@Slf4j
public class ZipFileUtiles {
    /**
     * @param srcFilePath 要压缩的文件
     * @Description 压缩文件，将文件压缩在源文件所在的目录下
     * @Return void
     * @Date 2019/8/11 15:16
     */
    public static void zipFile(String srcFilePath) {
        File srcFile = new File(srcFilePath);
        if (!srcFile.exists()) {
            return;
        }

        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        //获取到文件路径
        String zipFilePath = srcFile.getPath();
        //压缩文件的路径
        String destFilePath = zipFilePath.substring(0, zipFilePath.indexOf(".") + 1) + "zip";
        File dstFile = new File(destFilePath);
        try {
            //输出的文件
            fos = new FileOutputStream(dstFile);
            CheckedOutputStream cos = new CheckedOutputStream(fos, new CRC32());
            zos = new ZipOutputStream(cos);
            //数据写入
            writeDataToZip(srcFile, zos, "");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (zos != null) {
                IOUtils.closeQuietly(zos);
            }
            if (fos != null) {
                IOUtils.closeQuietly(fos);
            }
        }
    }

    /**
     * @param srcFile
     * @param zos
     * @param baseDir
     * @Description 数据写入压缩文件
     * @Return void
     * @Date 2019/8/28 17:18
     */
    private static void writeDataToZip(File srcFile, ZipOutputStream zos, String baseDir) {
        BufferedInputStream bis = null;
        try {
            //源文件流
            bis = new BufferedInputStream(new FileInputStream(srcFile));
            //创建压缩文件实体
            String name = baseDir + srcFile.getName();
            ZipEntry entry = new ZipEntry(name);
            zos.putNextEntry(entry);
            int count;
            byte data[] = new byte[16];
            //写入数据
            while ((count = bis.read(data, 0, 16)) != -1) {
                zos.write(data, 0, count);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                IOUtils.closeQuietly(bis);
            }
        }
    }

    /**
     * @param srcFilePath
     * @Description 压缩一个文件夹下的所有文件
     * @Return void
     * @Date 2019/8/24 15:59
     */
    public static void zipFilePath(String srcFilePath,String toZipFile) {
        System.out.println(srcFilePath);
        File srcFile = new File(srcFilePath);
        if (!srcFile.exists()) {
            log.error("文件路径错误");
            return;
        }
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        //获取到文件路径
        String zipFilePath = srcFile.getPath();
        //压缩文件的路径
        String destFilePath = toZipFile + "\\" + zipFilePath.substring(zipFilePath.lastIndexOf("\\") + 1) + ".zip";
        File dstFile = new File(destFilePath);
        try {
            fos = new FileOutputStream(dstFile);
            CheckedOutputStream cos = new CheckedOutputStream(fos, new CRC32());
            zos = new ZipOutputStream(cos);
            File[] files = srcFile.listFiles();
            //遍历文件压缩
            for (int i = 0; i < files.length; i++) {
                if (files[i].isDirectory()) {
                    zipDirectory(files[i], zos, files[i].getName() + "/");
                } else {
                    writeDataToZip(files[i], zos, "");
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (zos != null) {
                IOUtils.closeQuietly(zos);
            }
            if (fos != null) {
                IOUtils.closeQuietly(fos);
            }
        }
    }

    /**
     * @param directoryFile
     * @param zos
     * @param baseDir
     * @Description 遍历文件夹下的文件
     * @Return void
     * @Date 2019/8/28 18:05
     */
    private static void zipDirectory(File directoryFile, ZipOutputStream zos, String baseDir) {
        File[] files = directoryFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            if (files[i].isDirectory()) {
                zipDirectory(files[i], zos, baseDir + files[i].getName() + "/");
            } else {
                if (files[i].exists()) {
                    writeDataToZip(files[i], zos, baseDir);
                }
            }
        }
    }
}
